package de.szut.sudoku.cui;

import java.util.Observable;

import de.szut.sudoku.game.GameModelAction;
import de.szut.sudoku.game.GameModelActions;
import de.szut.sudoku.main.GameController;
import de.szut.sudoku.main.UserInterface;

/**
 * Controller class for the CUI
 * 
 * @author dqi12huisinga
 * 
 */
public class CUIController implements UserInterface {
	private static CUIController instance;
	private boolean gameEnded;
	private VisualFieldGenerator visualGenerator;

	/**
	 * Updates the CUI
	 */
	@Override
	public void update(Observable arg0, Object arg1) {
		GameModelAction action = (GameModelAction) arg1;
		// changes the value on the CUI
		if (action.getState() == GameModelActions.CHANGEVALUE) {
			// updates the value on the CUI
			visualGenerator.updateValue(action.getSudokuButtonChanger()
					.getChangedValue(), action.getSudokuButtonChanger()
					.getxPosition() - 1, action.getSudokuButtonChanger()
					.getyPosition() - 1);
			// generates the visual field
		} else if (action.getState() == GameModelActions.GENERATEFIELD) {
			visualGenerator.generateVisualFieldFromField(action
					.getSudokuFieldContainer().getCurrentField());
			// ends the game
		} else if (action.getState() == GameModelActions.ENDGAME) {
			// updates the value on the GUI
			visualGenerator.updateValue(action.getSudokuButtonChanger()
					.getChangedValue(), action.getSudokuButtonChanger()
					.getxPosition() - 1, action.getSudokuButtonChanger()
					.getyPosition() - 1);
			// tells the user that he won and exits the program
			System.out.println("You won!");
			gameEnded = true;
		}
	}

	/**
	 * Singleton for the CUI
	 * 
	 * @return
	 */
	public static CUIController getInstance() {
		if (instance == null) {
			instance = new CUIController();
		}
		return instance;
	}

	private CUIController() {
		visualGenerator = new VisualFieldGenerator();
	}

	/**
	 * Starts the UI and controls the input
	 */
	@Override
	public void startUI() {
		setGameEnded(false);
		ValueInput valueInput = new ValueInput();
		// tells the model that the game is supposed to get generated
		GameController.getInstance().getGame().generateField();
		// repeat the input until the game has ended
		while (!gameEnded) {
			// prints the visual field
			visualGenerator.printVisualField();
			// calls an input
			valueInput.inputValue();
			if (!valueInput.isInputHasError()) {
				// tells the model that the input is supposed to get changed
				GameController
						.getInstance()
						.getGame()
						.changeValue(valueInput.getValue(),
								valueInput.getInputxPosition(),
								valueInput.getInputyPosition());
			}
		}
		valueInput.closeScanner();

	}

	public boolean isGameEnded() {
		return gameEnded;
	}

	public void setGameEnded(boolean gameEnded) {
		this.gameEnded = gameEnded;
	}
}
